package com.jpro.module.system.util;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.BCUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;

@Slf4j
public class SM2Util {

    public static void main(String[] args) {
        String ciper = "6c114d33c3e039cdf76c3d8824b37500da7aaa503265c5cb2b2e0a5839b5b557c9f82fd7bc6dc40057f66ae4268f8ad2844fe06b8e63cc89c104774359ade780833d2e833b0d55cb84bb0d0ecb1393193912b84a968c688a9caa23d617ef4249e22e419f2ab38a4a";
        String privateKey = "308193020100301306072a8648ce3d020106082a811ccf5501822d0479307702010104209c2ace9bb703934e7055449458ed8cbc28ccf8b8edfceb4d1b087ca3869ede29a00a06082a811ccf5501822da14403420004148538e7e55d9c06a83259e2da973ede6aa7258594b9410355da3eafac5cade97303fc07a6f73bb4c48426f650f4fedf950d56c957ed8272bfe935f58da5f81b";
        decrypt(ciper, privateKey);
//        generateKey();
    }

    public static String decrypt(String ciphertext, String privateKey) {
        //手动加上前缀04
        String encryStr = "04" + ciphertext;
        SM2 sm2 = SmUtil.sm2(HexUtil.decodeHex(privateKey), null);
        byte[] decrypt = sm2.decrypt(encryStr, KeyType.PrivateKey);
        System.out.println(StrUtil.utf8Str(decrypt));
        return StrUtil.utf8Str(decrypt);
    }

    /**
     * 需要更换公钥 publicKeyQ (前端加密公钥)  私钥 privateKey（服务端解密私密） 参考
     * https://blog.csdn.net/weixin_43198844/article/details/135969882
     */
    public static void generateKey() {
        //创建sm2 对象
        SM2 sm = SmUtil.sm2();

        // sm2的加解密时有两种方式即 C1C2C3、 C1C3C2，
        sm.setMode(SM2Engine.Mode.C1C3C2);

        // 生成私钥
        String privateKey = HexUtil.encodeHexStr(sm.getPrivateKey().getEncoded());
        log.info("私钥: {}", privateKey);

        // 生成公钥
        String publicKey = HexUtil.encodeHexStr(sm.getPublicKey().getEncoded());
        log.info("公钥: {}", publicKey);

        // 生成私钥 D，以D值做为js端的解密私钥
        String privateKeyD = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm.getPrivateKey()));
        log.info("私钥D: {}", privateKeyD);

        // 生成公钥 Q，以Q值做为js端的加密公钥
        String publicKeyQ = HexUtil.encodeHexStr(((BCECPublicKey) sm.getPublicKey()).getQ().getEncoded(false));
        log.info("公钥Q: {}", publicKeyQ);
    }


}
